package com.todo.strategy.pipeline.application.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.strategy.pipeline.application.convert.PipelineRecordConvert;
import com.todo.strategy.pipeline.application.entity.bo.TransferOriginDataBO;
import com.todo.strategy.pipeline.application.entity.context.StrategyActionContext;
import com.todo.strategy.pipeline.application.handler.bizAction.AbstractStrategyActionHandle;
import com.todo.strategy.pipeline.application.handler.bizAction.StrategyActionFactory;
import com.todo.strategy.pipeline.application.service.PipelineService;
import com.todo.strategy.pipeline.infrastructure.entity.po.PipelineRecordPO;
import com.todo.strategy.pipeline.infrastructure.repository.PipelineRecordRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;

/**
 * @author azhebuxing
 * @date 2025/2/28 20:27
 * @description
 */
@Slf4j
@Service
public class PipelineServiceImpl implements PipelineService {

    @Resource
    private PipelineRecordRepository pipelineRecordRepository;
    @Resource
    private StrategyActionFactory strategyActionFactory;

    @Override
    public Boolean transferOriginData(TransferOriginDataBO transferOriginDataBO) {
        if (transferOriginDataBO == null || !transferOriginDataBO.isCheck()) {
            return false;
        }
        //1、先查询当前记录是否存在，存在则返回
        PipelineRecordPO originData = pipelineRecordRepository.queryPipelineRecordByUniKey(transferOriginDataBO.getUniKey(), transferOriginDataBO.getStrategyActionEnum());
        if (originData != null) {
            log.info("PipelineService#transferOriginData 当前记录已存在，直接返回 uniKey:[{}],strategyAction:[{}],operateAction:[{}]", transferOriginDataBO.getUniKey(), transferOriginDataBO.getStrategyActionEnum(), transferOriginDataBO.getOperateActionEnum());
            return true;
        }

        //2、插入记录
        PipelineRecordPO pipelineRecordPO = PipelineRecordConvert.buildIndertPipelineRecordPO(transferOriginDataBO);
        boolean inserted = pipelineRecordRepository.insertPipelineRecord(pipelineRecordPO);
        if (!inserted) {
            log.error("PipelineService#transferOriginData 插入记录失败 pipelineRecordPO:[{}]", JSONObject.toJSONString(pipelineRecordPO));
            throw new BizException(BizErrorCodeEnum.PROCESS_FAIL);
        }

        //3、调用对应的服务策略
        AbstractStrategyActionHandle strategyActionHandle = strategyActionFactory.getStrategyActionHandle(transferOriginDataBO.getStrategyActionEnum());
        if (strategyActionHandle == null) {
            log.info("PipelineService#transferOriginDataAsync 未找到对应的策略，默认成功 action:[{}]", transferOriginDataBO.getStrategyActionEnum());
            PipelineRecordPO updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, "未找到对应的策略");
            pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
            return true;
        }
        StrategyActionContext context = PipelineRecordConvert.buildStrategyActionContext(transferOriginDataBO);
        try {
            Boolean updated = strategyActionHandle.actionHandle(context);
            //4、更新记录状态
            PipelineRecordPO updatePipelineRecordPO;
            if (updated) {
                updatePipelineRecordPO = PipelineRecordConvert.buildSuccessPipelineRecordPO(pipelineRecordPO);
            } else {
                updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, "业务操作失败");
            }
            pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
        } catch (Exception ex) {
            //业务异常情况下数据保存
            PipelineRecordPO updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, ex.getMessage());
            pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
        }
        return true;
    }

    @Override
    public Boolean transferOriginDataAsync(TransferOriginDataBO transferOriginDataBO) {
        if (transferOriginDataBO == null || !transferOriginDataBO.isCheck()) {
            return false;
        }
        //1、先查询当前记录是否存在，存在则返回
        PipelineRecordPO originData = pipelineRecordRepository.queryPipelineRecordByUniKey(transferOriginDataBO.getUniKey(), transferOriginDataBO.getStrategyActionEnum());
        if (originData != null) {
            log.info("PipelineService#transferOriginDataAsync 当前记录已存在，直接返回 uniKey:[{}],strategyAction:[{}],operateAction:[{}]", transferOriginDataBO.getUniKey(), transferOriginDataBO.getStrategyActionEnum(), transferOriginDataBO.getOperateActionEnum());
            return true;
        }
        //2、插入记录
        PipelineRecordPO pipelineRecordPO = PipelineRecordConvert.buildIndertPipelineRecordPO(transferOriginDataBO);
        boolean inserted = pipelineRecordRepository.insertPipelineRecord(pipelineRecordPO);
        if (!inserted) {
            log.error("PipelineService#transferOriginDataAsync 插入记录失败 pipelineRecordPO:[{}]", JSONObject.toJSONString(pipelineRecordPO));
            throw new BizException(BizErrorCodeEnum.PROCESS_FAIL);
        }

        //3、异步执行
        CompletableFuture.runAsync(() -> {
            AbstractStrategyActionHandle strategyActionHandle = strategyActionFactory.getStrategyActionHandle(transferOriginDataBO.getStrategyActionEnum());
            if (strategyActionHandle == null) {
                log.info("PipelineService#transferOriginDataAsync 未找到对应的策略，默认成功 action:[{}]", transferOriginDataBO.getStrategyActionEnum());
                PipelineRecordPO updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, "未找到对应的策略");
                pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
                return;
            }
            StrategyActionContext context = PipelineRecordConvert.buildStrategyActionContext(transferOriginDataBO);
            try {
                Boolean updated = strategyActionHandle.actionHandle(context);
                //4、更新记录状态
                PipelineRecordPO updatePipelineRecordPO;
                if (updated) {
                    updatePipelineRecordPO = PipelineRecordConvert.buildSuccessPipelineRecordPO(pipelineRecordPO);
                } else {
                    updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, "业务操作失败");
                }
                pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
            } catch (Exception ex) {
                //业务异常情况下数据保存
                PipelineRecordPO updatePipelineRecordPO = PipelineRecordConvert.buildFailedPipelineRecordPO(pipelineRecordPO, ex.getMessage());
                pipelineRecordRepository.updatePipelineRecord(updatePipelineRecordPO);
            }
        });

        return true;
    }
}
